WPF and Silverlight Edition Basic Library > TreeView > TreeView Features > Load on Demand |
Instead of fully populating each node when the application starts, you can use a technique called "delayed loading" where nodes are populated on demand when the user expands them. This allows the application to load faster and use resources more efficiently
The implementation below hooks up an event hander for the Expanding event, so we can populate the node when the user tries to expand it. We also save the information we will need to populate the node in the Tag property. Finally, we add a dummy child node so the user will be able to expand this node and trigger the Expanding event that will populate the node.
Note: Instead of using the Tag property, we could also have derived a custom class from C1TreeViewItem and built all the delay-load logic into that class. This would be a more elegant approach, but unfortunately WPF doesn't support template inheritance. If you derive a class from a class that has a template (such as Button or C1TreeViewItem), the template is not inherited, and you have to provide a template yourself or your derived class will be just an empty control. |
To implement the delayed loading nodes, use the following code:
C# |
Copy Code
|
---|---|
public Page() { InitializeComponent(); // No changes here. // ... // Initialize the C1TreeView InitializeTreeView(); } void InitializeTreeView() { // Remove items that were added at design time _tv.Items.Clear(); // Scan every type in the assembly foreach (Type t in _tv.GetType().Assembly.GetTypes()) { if (t.IsPublic && !t.IsSpecialName && !t.IsAbstract) { // Add node for this type C1TreeViewItem node = new C1TreeViewItem(); node.Header = t.Name; node.FontWeight = FontWeights.Bold; _tv.Items.Add(node); // Add subnodes for properties, events, and methods node.Items.Add(CreateMemberNode("Properties", t, MemberTypes.Property)); node.Items.Add(CreateMemberNode("Events", t, MemberTypes.Event)); node.Items.Add(CreateMemberNode("Methods", t, MemberTypes.Method)); } } } C1TreeViewItem CreateMemberNode(string header, MemberTypes memberTypes) { // Create the node C1TreeViewItem node = new C1TreeViewItem(); node.Header = header; node.Foreground = new SolidColorBrush(Colors.DarkGray); // Hook up event hander to populate the node before expanding it node.Expanding += node_Expanding; // Save information needed to populate the node node.Tag = memberTypes; // Add a dummy node so this node can be expanded node.Items.Add(new C1TreeViewItem()); node.IsExpanded = false; // Finish return node; } //populate the node void node_Expanding(object sender, RoutedEventArgs e) { // Get the node that fired the event C1TreeViewItem node = sender as C1TreeViewItem; // Unhook event handler (we'll populate the node and be done with it) node.Expanding -= node_Expanding; // Remove dummy node node.Items.Clear(); // Populate the node Type type = (Type)node.Parent.Tag; MemberTypes memberTypes = (MemberTypes)node.Tag; BindingFlags bf = BindingFlags.Public | BindingFlags.Instance; foreach (MemberInfo mi in type.GetMembers(bf)) { if (mi.MemberType == memberTypes) { if (!mi.Name.StartsWith("get_") && !mi.Name.StartsWith("set_")) { C1TreeViewItem item = new C1TreeViewItem(); item.Header = mi.Name; item.FontSize = 12; node.Items.Add(item); } } } } |